

using Godot;
using System;

public partial class SmoothCamera : Camera2D
{
    // --- 移动相关 ---
    [Export] public Node2D Target;
    [Export] public float DefaultSmoothSpeed = 8.0f;
    [Export] public float SmoothTime = 20.0f;

    // --- 缩放相关 (新增) ---
    [ExportGroup("Zoom Settings")] // 在检查器里分组显示，好看一点
    [Export] public float ZoomSpeed = 10.0f; // 缩放的平滑速度
    [Export] public float MinZoom = 0.2f;    // 最小缩放 (拉远的最大限度)

    [Export] public float defaultZoom = 0.25f;
    [Export] public float MaxZoom = 3.0f;    // 最大缩放 (拉近的最大限度)
    [Export] public float ZoomFactor = 0.1f; // 每次滚动滚轮缩放的比例 (10%)

    // 用于记录目标缩放值，初始化为Vector2(1, 1)
    private Vector2 _targetZoom;

    [ExportGroup("Shake Settings")]
    // 震动参数
    private float _shakeStrength = 0.0f;
    private float _shakeFade = 5.0f;
    private RandomNumberGenerator _rng = new RandomNumberGenerator();

    public override void _Ready()
    {
        // 游戏开始时，目标缩放值 = 最小缩放
        _targetZoom = new Vector2(defaultZoom, defaultZoom);
        if (SmoothTime <= 0)
        {
            SmoothTime = 0.1f;
        }

    }

    // 处理输入事件 (专门用来处理鼠标点击、键盘等单次触发的事件)
    public override void _UnhandledInput(InputEvent @event)
    {
        // 检查是不是鼠标按键事件
        if (@event is InputEventMouseButton mouseEvent)
        {
            // 只有按下时才触发，抬起时不触发
            if (mouseEvent.IsPressed())
            {
                if (mouseEvent.ButtonIndex == MouseButton.WheelUp)
                {
                    // 滚轮向上 -> 拉近镜头 -> Zoom值变大
                    // 使用乘法会让缩放手感更自然 (1 -> 1.1 -> 1.21...)
                    // 如果你喜欢线性缩放，改成 _targetZoom += Vector2.One * ZoomFactor;
                    _targetZoom *= (1 + ZoomFactor);
                }
                else if (mouseEvent.ButtonIndex == MouseButton.WheelDown)
                {
                    // 滚轮向下 -> 拉远镜头 -> Zoom值变小
                    _targetZoom *= (1 - ZoomFactor);
                }

                // 限制缩放范围 (Clamp)，防止缩得太小或太大
                // X和Y轴同时限制
                _targetZoom.X = Mathf.Clamp(_targetZoom.X, MinZoom, MaxZoom);
                _targetZoom.Y = Mathf.Clamp(_targetZoom.Y, MinZoom, MaxZoom);
            }
        }
    }

    public override void _PhysicsProcess(double delta)
    {
        // 1. 处理位置平滑跟随
        if (Target != null)
        {
            Vector2 targetPos = Target.GlobalPosition;

            // --- 核心修改 ---
            // 原来的算法: float t = Mathf.SmoothStep(0, 1, (float)delta * SmoothSpeed);
            // 问题: SmoothStep 是用来做曲线的，不适合直接做 Lerp 的 weight，会导致跟随有粘滞感。

            // 推荐算法: 指数衰减 (Exponential Decay)
            // 这种写法不仅丝滑，而且完全不受帧率波动影响
            // SmoothSpeed 建议值: 5.0f (慢/电影感) ~ 15.0f (快/动作感)
            float t = 1.0f - Mathf.Exp(-DefaultSmoothSpeed * (float)delta);

            // 如果距离太远（比如传送），直接瞬移，防止镜头飞越半个地图
            if (GlobalPosition.DistanceSquaredTo(targetPos) > 5000 * 5000)
            {
                GlobalPosition = targetPos;
            }
            else
            {
                GlobalPosition = GlobalPosition.Lerp(targetPos, t);
            }
        }

        // 2. 处理缩放平滑
        // 同样的指数衰减算法
        float zoomT = 1.0f - Mathf.Exp(-ZoomSpeed * (float)delta);
        Zoom = Zoom.Lerp(_targetZoom, zoomT);
        if (_shakeStrength > 0)
        {
            _shakeStrength = Mathf.Lerp(_shakeStrength, 0, _shakeFade * (float)delta);

            // 随机偏移
            Offset = new Vector2(
                _rng.RandfRange(-_shakeStrength, _shakeStrength),
                _rng.RandfRange(-_shakeStrength, _shakeStrength)
            );
        }
        else
        {
            Offset = Vector2.Zero;
        }
    }

    // 接口：调用震动,传入震动强度
    public void ApplyShake(float strength)
    {
        _shakeStrength = strength;
    }

    //如果按下q键，震动摄像机


    //testing
    // public override void _Process(double delta)
    // {
    //     if (Input.IsKeyPressed(Key.Q))
    //     {
    //         ApplyShake(50.0f); // 震动强度为5，可以根据需要调整
    //     }
    // }
}